﻿using Fast;
using Fast.Extensions;
using Fast.Extensions.EventBus;
using Fast.Extensions.EventBus.RabbitMQ;
using System;
using System.Linq;

namespace Microsoft.Extensions.DependencyInjection
{
    [SkipScan]
    public static class EventBusRabbitMqServiceCollectionExtensions
    {
        /// <summary>
        /// 添加 基于RabbitMQ的EventBus 服务
        /// </summary>r
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddEventBusWithRabbitMQ(this IServiceCollection services)
        {
            services.AddRabbitMQ();
            services.AddConfigureOptions<FastRabbitMqEventBusOptions>();
            services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
            services.AddSingleton<FastEventBusRabbitMQ>();
            services.AddEventHandler();
            return services;
        }


        private static IServiceCollection AddEventHandler(this IServiceCollection services)
        {
            var eventHandlerTypes = App.Types.ToList();

            var enableDeadLetterExchange = App.GetConfig<FastRabbitMqEventBusOptions>("RabbitMQ:EventBus", true).EnableDeadLetterExchange.Value;

            Func<Type, bool> hasImplementedHandler = t => t.HasImplementedTargetGeneric(typeof(IIntegrationEventHandler<>));
            Func<Type, bool> hasImplementedExceptionHandler = t => t.HasImplementedTargetGeneric(typeof(IIntegrationEventExceptionHandler<>));
            Func<Type, bool> hasImplementedTargetGeneric = t => enableDeadLetterExchange ? (hasImplementedHandler(t) || hasImplementedExceptionHandler(t)) : hasImplementedHandler(t);

            var types = eventHandlerTypes.Where(t => t.IsClass && t.IsPublic && !t.IsAbstract && !t.IsGenericType && hasImplementedTargetGeneric(t)).ToList();
            foreach (var type in types)
            {
                services.AddTransient(type);
            }

            return services;
        }
    }
}
